// Copyright (C) 1998-2008, Sumisho Computer Systems Corp. All Rights Reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @author Akira Mori
 */

package com.curlap.orb.context;

import java.lang.reflect.InvocationTargetException;
import javax.servlet.ServletContext;

import org.apache.commons.beanutils.MethodUtils;

/**
 * Seasar2ApplicationContext
 *   seasar2 framework integration 
 *   http://www.seasar.org/
 */
public class Seasar2ApplicationContext extends AbstractApplicationContext {

	public Seasar2ApplicationContext(ServletContext context) throws ApplicationContextException
	{
		try {
			Class cls = Class.forName("org.seasar.framework.container.servlet.SingletonS2ContainerInitializer");
			Object obj = cls.getConstructor(new Class[0]).newInstance(new Object[0]);
			if (context.getInitParameter("configPath") != null) { 
				MethodUtils.invokeMethod(obj, "setConfigPath", new Object[]{context.getInitParameter("configPath")});
			}
			MethodUtils.invokeMethod(obj, "setApplication", new Object[]{context});
			MethodUtils.invokeMethod(obj, "initialize", new Object[0]);
		}catch (IllegalArgumentException e) {
			throw new ApplicationContextException(e);
		}catch (SecurityException e) {
			throw new ApplicationContextException(e);
		}catch (InstantiationException e) {
			throw new ApplicationContextException(e);
		}catch (ClassNotFoundException e) {
			throw new ApplicationContextException(e);
		}catch (NoSuchMethodException e) {
			throw new ApplicationContextException(e);
		}catch (IllegalAccessException e) {
			throw new ApplicationContextException(e);
		}catch (InvocationTargetException e) {
			throw new ApplicationContextException(e);
		}
	}

	@Override
	public Object getObject(String name) throws ApplicationContextException {
		try {
			Class cls = Class.forName("org.seasar.framework.container.factory.SingletonS2ContainerFactory");
			Object obj = MethodUtils.invokeStaticMethod(cls, "getContainer",new Object[0]);
			return MethodUtils.invokeMethod(obj, "getComponent",new Object[]{name});
		} catch (ClassNotFoundException e) {
			throw new ApplicationContextException(e);
		} catch (NoSuchMethodException e) {
			throw new ApplicationContextException(e);
		} catch (IllegalAccessException e) {
			throw new ApplicationContextException(e);
		} catch (InvocationTargetException e) {
			throw new ApplicationContextException(e);
		}
	}

	@Override
	public String[] getObjectNames() throws ApplicationContextException {

		Class cls;
		try {
			cls = Class.forName("org.seasar.framework.container.factory.SingletonS2ContainerFactory");
			Object obj = MethodUtils.invokeStaticMethod(cls, "getContainer",new Object[0]);
			Integer componentSize = (Integer)MethodUtils.invokeMethod(obj, "getComponentDefSize",new Object[0]);
			String[] objectNames = new String[componentSize];
			for (int i = 0; i < componentSize;i++) {
				Object componentDef = MethodUtils.invokeMethod(obj, "getComponentDef",new Object[]{i});
				objectNames[i] = (String)MethodUtils.invokeMethod(componentDef, "getComponentName",new Object[0]);
			}
			return objectNames;
		} catch (ClassNotFoundException e) {
			throw new ApplicationContextException(e);
		} catch (NoSuchMethodException e) {
			throw new ApplicationContextException(e);
		} catch (IllegalAccessException e) {
			throw new ApplicationContextException(e);
		} catch (InvocationTargetException e) {
			throw new ApplicationContextException(e);
		}
	}

	@Override
	public Class getObjectType(String name) throws ApplicationContextException {
		return getObject(name).getClass(); 
	}

	@Override
	public void setObject(String name, Object value) throws ApplicationContextException {
		// do nothing
	}
}
